import mongoose, {Model, Schema} from 'mongoose';
import {v1} from 'uuid';
import {cloneDeep} from "lodash";
import {IKeyValue, IKT} from "../core/CpcInterface";
// 每张表的只读属性
const ModelReadOnly: any = {
    project: ["id", "date"],
    router: ["id", "date", "projectId"],
};

export const ModelUtil: any = {
    // 项目
    project: new Schema({
        id: {type: String, required: true, unique: true, default: () => v1()},// 项目id
        name: {type: String, required: true},// 项目名称
        disable: {type: Boolean},// 项目是否禁止
        path: {type: String, required: true},// 项目路径
        date: {type: String, required: true, default: () => new Date().getTime()}// 创建时间
    }),
    // 路由
    router: new Schema({
        id: {type: String, required: true, unique: true, default: () => v1()},// 路由id
        projectId: {type: String, required: true},// 项目id
        description: {type: String},// 路由描述
        path: {type: String, required: true},// 路由路径
        disable: {type: Boolean},// 是否禁止
        handler: {type: String, required: true},// TODO 重新设计
        method: {type: String, required: true},// 方式
        date: {type: String, required: true, default: () => new Date().getTime()}// 创建时间
    })
}

// 扩展模型的方法
const ModelStatics: any = {
    // 分页查询
    async findByPage(filter: IKeyValue, fields: IKeyValue, page = 1, limit = 10) {
        const count = await this.countDocuments(filter);
        if (count === 0) {
            return {count, list: []};
        }
        const list = await this.find(filter, fields).skip((page - 1) * limit).limit(limit).exec();
        return {count, list};
    },
    // 移除只读的属性
    removeModelReadOnly(fields: IKeyValue) {
        const result = cloneDeep(fields);
        for (let field of this._modelReadOnly) {
            delete result[field];
        }
        return result;
    },
    // 移除只读属性后，在更新
    async updateOneByReadOnly(filter: IKeyValue, fields: IKeyValue) {
        const result = this.removeModelReadOnly(fields);
        return await this.updateOne(filter, {$set: result});
    }
}
for (let key of Object.keys(ModelUtil)) {
    // 扩展模型的方法
    for (let funcName of Object.keys(ModelStatics)) {
        ModelUtil[key].statics[funcName] = ModelStatics[funcName];
    }
    // 绑定只读属性
    ModelUtil[key].statics._modelReadOnly = ModelReadOnly[key];
    ModelUtil[key] = mongoose.model(key, ModelUtil[key], key);
}
